import gradio as gr
import numpy as np

# https://blog.csdn.net/Hfengxiang/article/details/140783921
def greet(name):
    return "Hello" + name + "!"
'''
请升级为 Pro 会员再使用该翻译服务

升级后，请刷新页面再次翻译。

请升级为 Pro 会员再使用该翻译服务

升级后，请刷新页面再次翻译。

fn：包装接口的函数。通常是机器学习模型的预测函数。函数的每个参数对应于一个输入组件，函数应返回单个值或值元组，元组中的每个元素对应于一个输出组件。
inputs：单个 Gradio 组件或 Gradio 组件列表。组件可以作为实例化对象传递，也可以通过其字符串快捷方式引用。输入组件的数量应与 fn 中的参数数量匹配。如果设置为 None，则仅显示输出组件。
outputs：单个 Gradio 组件，或 Gradio 组件列表。组件可以作为实例化对象传递，也可以通过其字符串快捷方式引用。输出组件的数量应与 fn 返回的值的数量相匹配。如果设置为 None，则仅显示输入组件。
examples：函数的示例输入;如果提供，则显示在 UI 组件下方，单击该组件可填充界面。应该是嵌套列表，其中外部列表由样本组成，每个内部列表由对应于每个输入组件的输入组成。还可以提供示例目录的字符串路径，但它应该位于运行 gradio 应用程序的 python 文件的目录中。如果有多个 input 组件并且提供了一个目录，则目录中必须存在一个 log.csv 文件才能链接相应的 inputs。
cache_examples：如果为 True，则在服务器中缓存示例，以便在示例中快速运行。如果 'fn' 是生成器函数，则最后生成的值将用作输出。HuggingFace Spaces 中的默认选项为 True。其他位置的默认选项为 False。
examples_per_page：如果提供了示例，则每页要显示多少个。
live：如果任何输入发生变化，是否应该自动重新运行接口。
title： 接口的标题;如果提供，则以大字体显示在输入和输出组件上方。在浏览器窗口中打开时也用作选项卡标题。
description：接口的描述;如果提供，则以常规字体显示在输入和输出组件的上方和标题的下方。接受 Markdown 和 HTML 内容。
article：解释界面的扩展文章;如果提供，则以常规字体显示在输入和输出组件下方。接受 Markdown 和 HTML 内容。
thumbnail：在社交媒体上共享 Web 演示时用作显示图像的图像的字符串路径或 URL。
theme：要使用的主题，从 gradio.themes 加载。
css：自定义 css 作为字符串或 css 文件的路径。此 css 将包含在演示网页中。
allow_flagging：“never”、“auto”或“manual”之一。如果为“从不”或“自动”，则用户将不会看到用于标记输入和输出的按钮。如果为 “manual”，用户将看到一个标记按钮。如果为 “auto”，则用户提交的每个输入都将被自动标记（输出不会被标记）。如果为 “manual”，则当用户单击 flag 按钮时，输入和输出都会被标记。此参数可通过环境变量 GRADIO_ALLOW_FLAGGING 进行设置;否则默认为 “manual”。
flagging_options：如果提供，则允许用户在标记时从选项列表中进行选择。仅当 allow_flagging 为 “手动” 时适用。可以是 （label， value） 形式的元组列表，其中 label 是将显示在按钮上的字符串，value 是将存储在标记 CSV 中的字符串;或者它可以是字符串列表 [“X”， “Y”]，在这种情况下，值将是字符串列表，标签将是 [“Flag as X”， “Flag as Y”] 等。
flagging_dir：存储已标记数据的目录的名称。
flagging_callback：None 或 FlaggingCallback 的子类的实例，在标记样本时将调用该实例。如果设置为 None，将创建一个 gradio.flagging.CSVLogger 实例，并将日志保存到 flagging_dir 中的本地 CSV 文件。默认为 None。
analytics_enabled：是否允许基本遥测。如果为 None，将使用GRADIO_ANALYTICS_ENABLED环境变量（如果已定义），或默认为 True。
batch：如果为 True，则函数应处理一批输入，这意味着它应接受每个参数的输入值列表。列表的长度应相等（并且最大长度为 'max_batch_size'）。然后，该函数*需要*返回一个列表元组（即使只有 1 个输出组件），元组中的每个列表对应一个输出组件。
max_batch_size：如果从队列中调用此函数，则要一起批处理的最大输入数（仅当 batch=True 时相关）
api_name：定义端点在 API 文档中的显示方式。可以是字符串、None 或 False。如果设置为字符串，则端点将在 API 文档中以给定的名称公开。如果为 None，则预测函数的名称将用作 API 端点。如果为 False，则端点将不会在 API 文档中公开，并且下游应用程序（包括那些“gr.load”此应用程序的应用程序）将不能使用此事件。
allow_duplication： 如果为 True，则将在 Hugging Face Spaces 上显示一个 'Duplicate Spaces' 按钮。
concurrency_limit：如果设置，则这是可以同时运行的此事件的最大数量。可以设置为 None 表示没有concurrency_limit（此事件的任意数量的可以同时运行）。设置为 “default” 以使用默认并发限制（由 '.queue（）' 中的 'default_concurrency_limit' 参数定义，该参数本身默认为 1）。
js：首次加载 demo 时要运行的自定义 js 或 js 文件的路径。此 javascript 将包含在演示网页中。
head：要插入到演示网页头部的自定义 html。这可用于向页面添加自定义元标记、脚本、样式表等。
additional_inputs：单个 Gradio 组件，或 Gradio 组件列表。组件可以作为实例化对象传递，也可以通过其字符串快捷方式引用。这些组件将在主 input 组件下方的折叠面板上呈现。默认情况下，不会显示其他输入组件。
additional_inputs_accordion：如果提供了字符串，则这是 'gr.Accordion“用于包含其他输入。一个 'gr.Accordion' 对象，以配置包含其他输入的容器的其他属性。默认为 'gr.accordion（label=“Additional Inputs”， open=False）'。仅当提供 'additional_inputs' 时，才使用此参数。
submit_btn：用于提交输入的按钮。默认为 'gr.button（“提交”， variant=“primary”）'。如果接口仅输出，则此参数不适用，在这种情况下，提交按钮始终显示“生成”。可以设置为 string （成为按钮标签） 或 'gr。Button 对象（允许进行更多自定义）。
stop_btn：用于停止界面的按钮。默认为 'gr.Button（“Stop”， variant=“stop”， visible=False）'。可以设置为 string （成为按钮标签） 或 'gr。Button 对象（允许进行更多自定义）。
clear_btn：用于清除输入的按钮。默认为 'gr.button（“Clear”， variant=“secondary”）'。可以设置为 string （成为按钮标签） 或 'gr。Button 对象（允许进行更多自定义）。
'''
# demo = gr.Interface(fn=greet, inputs="text", outputs="text")
# demo.launch()
'''
 Interface类通过以下三个参数进行初始化：

    fn：包装的函数

    inputs：输入组件类型，（例如：“text”、"image）

    ouputs：输出组件类型，（例如：“text”、"image）

通过这三个参数，我们可以快速创建一个接口并发布他们。

    最常用的基础模块构成。

        应用界面：gr.Interface(简易场景), gr.Blocks(定制化场景)

        输入输出：gr.Image(图像), gr.Textbox(文本框), gr.DataFrame(数据框), gr.Dropdown(下拉选项), gr.Number(数字), gr.Markdown, gr.Files

        控制组件：gr.Button(按钮)

        布局组件：gr.Tab(标签页), gr.Row(行布局), gr.Column(列布局)

'''

# # 自定义输入组件
# demo = gr.Interface(fn=greet, inputs=gr.Textbox(lines=3, placeholder="Name here..", label="my input"), outputs="text")
# demo.launch()

# 多个输入和输出
#该函数有3个输入参数和2个输出参数
# def greet(name, is_morning, temperature):
#     salutation = "Good morning" if is_morning else "Good evening"
#     greeting = f"{salutation} {name}. It is {temperature} degrees today"
#     celsius = (temperature - 32) * 5 / 9
#     return greeting, round(celsius, 2)
#
# demo = gr.Interface(fn=greet, inputs=['text', "checkbox", gr.Slider(0,100)], outputs=['text','number'])
#
# demo.launch()

# 图像组件 Gradio支持许多类型的组件，如image、dataframe、video。使用示例如下：
# import numpy as np
# import gradio as gr
# def sepia(input_img):
#     #处理图像
#     sepia_filter = np.array([
#         [0.393, 0.769, 0.189],
#         [0.349, 0.686, 0.168],
#         [0.272, 0.534, 0.131]
#     ])
#     sepia_img = input_img.dot(sepia_filter.T)
#     sepia_img /= sepia_img.max()
#     return sepia_img
# #shape设置输入图像大小
# demo = gr.Interface(sepia, gr.Image(height=200, width=200), "image")
# demo.launch()


# 简单计算器模板实时变化, 在Interface添加live=True参数，只要输入发生变化，结果马上发生改变
# def calculator(num1, operation, num2):
#     if operation == "add":
#         return num1 + num2
#     elif operation == "subtract":
#         return num1 - num2
#     elif operation == "multiply":
#         return num1 * num2
#     elif operation == "divide":
#         return num1 / num2
#
#
# iface = gr.Interface(
#     calculator,
#     ["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
#     "number",
#     live=True,
# )
#
# iface.launch()

# 改进
# def calculator(num1, operation, num2):
#     if operation == "add":
#         return num1 + num2
#     elif operation == "subtract":
#         return num1 - num2
#     elif operation == "multiply":
#         return num1 * num2
#     elif operation == "divide":
#         if num2 == 0:
#             # 设置报错弹窗
#             raise gr.Error("Cannot divide by zero!")
#         return num1 / num2
#
# demo = gr.Interface(
#     calculator,
#     # 设置输入
#     [
#         "number",
#         gr.Radio(["add", "subtract", "multiply", "divide"]),
#         "number"
#     ],
#     # 设置输出
#     "number",
#     # 设置输入参数示例
#     examples=[
#         [5, "add", 3],
#         [4, "divide", 2],
#         [-4, "multiply", 2.5],
#         [0, "subtract", 1.2],
#     ],
#     # 设置网页标题
#     title="Toy Calculator",
#     # 左上角的描述文字
#     description="Here's a sample toy calculator. Enjoy!",
#     # 左下角的文字
#     article = "Check out the examples",
# )
# demo.launch()

# 保存会话记录
# import random
# def chat(message, history):
#     history = history or []
#     message = message.lower()
#     if message.startswith("how many"):
#         response = random.randint(1, 10)
#     elif message.startswith("how"):
#         response = random.choice(["Great", "Good", "Okay", "Bad"])
#     elif message.startswith("where"):
#         response = random.choice(["Here", "There", "Somewhere"])
#     else:
#         response = "I don't know"
#     history.append((message, response))
#     return history, history
# #设置一个对话窗
# chatbot = gr.Chatbot()
# demo = gr.Interface(
#     chat,
#     # 添加state组件
#     ["text", "state"],
#     [chatbot, "state"],
#     # 设置没有保存数据的按钮
#     allow_flagging="never",
# )
# demo.launch()

# 输入是实时视频流或者音频流，那么意味这数据不停地发送到后端，这是可以采用streaming模式处理数据
# def flip(im):
#     return np.flipud(im)
#
# demo = gr.Interface(
#     flip,
#     gr.Image(sources=["webcam"], streaming=True),
#     "image",
#     live=True
# )
# demo.launch()


# Blocks构建单应用
# def greet(name):
#     return "Hello " + name + "!"
# with gr.Blocks() as demo:
#     #设置输入组件
#     name = gr.Textbox(label="Name")
#     # 设置输出组件
#     output = gr.Textbox(label="Output Box")
#     #设置按钮
#     greet_btn = gr.Button("Greet")
#     #设置按钮点击事件
#     greet_btn.click(fn=greet, inputs=name, outputs=output)
# demo.launch()


# Blocks构建多应用
# def flip_text(x):
#     return x[::-1]
#
#
# def flip_image(x):
#     return np.fliplr(x)
#
#
# with gr.Blocks() as demo:
#     # 用markdown语法编辑输出一段话
#     gr.Markdown("Flip text or image files using this demo.")
#     # 设置tab选项卡
#     with gr.Tab("Flip Text"):
#         # Blocks特有组件，设置所有子组件按垂直排列
#         # 垂直排列是默认情况，不加也没关系
#         with gr.Column():
#             text_input = gr.Textbox()
#             text_output = gr.Textbox()
#             text_button = gr.Button("Flip")
#     with gr.Tab("Flip Image"):
#         # Blocks特有组件，设置所有子组件按水平排列
#         with gr.Row():
#             image_input = gr.Image()
#             image_output = gr.Image()
#         image_button = gr.Button("Flip")
#     # 设置折叠内容
#     with gr.Accordion("Open for More!"):
#         gr.Markdown("Look at me...")
#     text_button.click(flip_text, inputs=text_input, outputs=text_output)
#     image_button.click(flip_image, inputs=image_input, outputs=image_output)
# demo.launch()

# 在某些情况下，你可能想显示一连串的输出，而不是单一的输出。例如，你可能有一个图像生成模型，如果你想显示在每个步骤中生成的图像，
# 从而得到最终的图像。在这种情况下，你可以向Gradio提供一个生成器函数，而不是一个常规函数。下面是一个生成器的例子，每隔1秒返回1张图片。
import time
#生成steps张图片，每隔1秒钟返回
# def fake_diffusion(steps):
#     for _ in range(steps):
#         time.sleep(1)
#         image = np.random.randint(255, size=(300, 600, 3))
#         yield image
# demo = gr.Interface(fake_diffusion,
#                     #设置滑窗，最小值为1，最大值为10，初始值为3，每次改动增减1位
#                     inputs=gr.Slider(1, 10, value=3, step=1),
#                     outputs="image")
# #生成器必须要queue函数
# demo.queue()
# demo.launch()


# Blocks事件
# 任何输入的组件内容都是可编辑的，而输出组件默认是不能编辑的。如果想要使得输出组件内容可编辑，设置interactive=True即可
# def greet(name):
#     return "Hello " + name + "!"
# with gr.Blocks() as demo:
#     name = gr.Textbox(label="Name")
#     # 不可交互
#     # output = gr.Textbox(label="Output Box")
#     # 可交互
#     output = gr.Textbox(label="Output", interactive=True)
#     greet_btn = gr.Button("Greet")
#     greet_btn.click(fn=greet, inputs=name, outputs=output)
# demo.launch()

# 事件设置
# 我们可以为不同的组件设置不同事件，如为输入组件添加change事件
# def welcome(name):
#     return f"Welcome to Gradio, {name}!"
# with gr.Blocks() as demo:
#     gr.Markdown(
#     """
#     # Hello World!
#     Start typing below to see the output.
#     """)
#     inp = gr.Textbox(placeholder="What is your name?")
#     out = gr.Textbox()
#     #设置change事件
#     inp.change(fn = welcome, inputs = inp, outputs = out)
# demo.launch()

# 输出的多个值用于更新对应的输入和输出
# with gr.Blocks() as demo:
#     food_box = gr.Number(value=10, label="Food Count")
#     status_box = gr.Textbox()
#     def eat(food):
#         if food > 0:
#             return food - 1, "full"
#         else:
#             return 0, "hungry"
#     gr.Button("EAT").click(
#         fn=eat,
#         inputs=food_box,
#         #根据返回值改变输入组件和输出组件
#         outputs=[food_box, status_box]
#     )
# demo.launch()



# 选择不同的类型给到对应的动态输出
# def change_textbox(choice):
#     # 根据不同输入对输出控件进行更新
#     if choice == "short":
#         return gr.update(lines=2, visible=True, value="Short story: ")
#     elif choice == "long":
#         return gr.update(lines=8, visible=True, value="Long story...")
#     else:
#         return gr.update(visible=False)
#
#
# with gr.Blocks() as demo:
#     radio = gr.Radio(
#         ["short", "long", "none"], label="Essay Length to Write?"
#     )
#     text = gr.Textbox(lines=2, interactive=True)
#     radio.change(fn=change_textbox, inputs=radio, outputs=text)
# demo.launch()

# 组件垂直排列与嵌套
# 可以通过Row函数和Column函数生成不同复杂的布局
# with gr.Blocks() as demo:
#     with gr.Row():
#         text1 = gr.Textbox(label="t1")
#         slider2 = gr.Textbox(label="s2")
#         drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
#     with gr.Row():
#         # scale与相邻列相比的相对宽度。例如，如果列A的比例为2，列B的比例为1，则A的宽度将是B的两倍。
#         # min_width设置最小宽度，防止列太窄
#         with gr.Column(scale=2, min_width=600):
#             text1 = gr.Textbox(label="prompt 1")
#             text2 = gr.Textbox(label="prompt 2")
#             inbtw = gr.Button("Between")
#             text4 = gr.Textbox(label="prompt 1")
#             text5 = gr.Textbox(label="prompt 2")
#         with gr.Column(scale=1, min_width=600):
#             img1 = gr.Image("../0/1.jpg")
#             btn = gr.Button("Go")
# demo.launch()


# 输出可视化从无到有
# with gr.Blocks() as demo:
#     # 出错提示框
#     error_box = gr.Textbox(label="Error", visible=False)
#     # 输入框
#     name_box = gr.Textbox(label="Name")
#     age_box = gr.Number(label="Age")
#     symptoms_box = gr.CheckboxGroup(["Cough", "Fever", "Runny Nose"])
#     submit_btn = gr.Button("Submit")
#     # 输出不可见
#     with gr.Column(visible=False) as output_col:
#         diagnosis_box = gr.Textbox(label="Diagnosis")
#         patient_summary_box = gr.Textbox(label="Patient Summary")
#     def submit(name, age, symptoms):
#         if len(name) == 0:
#             return {error_box: gr.update(value="Enter name", visible=True)}
#         if age < 0 or age > 200:
#             return {error_box: gr.update(value="Enter valid age", visible=True)}
#         return {
#             output_col: gr.update(visible=True),
#             diagnosis_box: "covid" if "Cough" in symptoms else "flu",
#             patient_summary_box: f"{name}, {age} y/o"
#         }
#     submit_btn.click(
#         submit,
#         [name_box, age_box, symptoms_box],
#         [error_box, diagnosis_box, patient_summary_box, output_col],
#     )
# demo.launch()



# # 这里用的是id属性设置
# with gr.Blocks(css="#warning {background-color: red}") as demo:
#     box1 = gr.Textbox(value="Good Job", elem_id="warning")
#     box2 = gr.Textbox(value="Failure")
#     box3 = gr.Textbox(value="None", elem_id="warning")
# demo.launch()


# import gradio as gr
#
# with gr.Blocks() as demo:
#     with gr.Row():
#         text1 = gr.Textbox(label="t1")
#         slider2 = gr.Textbox(label="s2")
#         drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
#     with gr.Row():
#         with gr.Column(scale=1, min_width=600):
#             text1 = gr.Textbox(label="prompt 1")
#             text2 = gr.Textbox(label="prompt 2")
#             inbtw = gr.Button("Between")
#             text4 = gr.Textbox(label="prompt 1")
#             text5 = gr.Textbox(label="prompt 2")
#         with gr.Column(scale=2, min_width=600):
#             img1 = gr.Image("/home/xjl/pythonCode/play_test/data2/14.jpg")
#             btn = gr.Button("Go")
#
# demo.launch()

#进度条
# import gradio as gr
# import time
#
#
# # 定义一个模拟长时间运行的任务
# def long_running_task(progress=gr.Progress()):
#     total_steps = 100
#     for i in range(total_steps):
#         # 模拟任务的进展
#         time.sleep(0.1)
#         # 更新进度条
#         progress((i + 1, total_steps), desc=f"Step {i + 1}/{total_steps}")
#     return "任务完成！"
#
#
# # 创建 Gradio 界面
# with gr.Blocks() as demo:
#     with gr.Row():
#         # 创建一个按钮
#         button = gr.Button("开始任务")
#
#     with gr.Row():
#         # 创建一个 Textbox 组件来显示任务完成的消息
#         output_text = gr.Textbox(label="输出")
#
#     # 将按钮点击事件绑定到 long_running_task 函数
#     button.click(fn=long_running_task, outputs=output_text)
#
# # 启动 Gradio 应用
# demo.launch()

#学习then的用法
# import gradio as gr
#
#
# def generate_text(prompt):
#     # 假设这是一个生成文本的函数
#     return f"Generated text for: {prompt}"
#
#
# def regenerate_text():
#     # 这个函数会在重新生成文本时被调用
#     return "Regenerated text"
#
#
# with gr.Blocks() as demo:
#     prompt = gr.Textbox(label="Enter your prompt")
#     output = gr.Textbox(label="Output")
#
#     # 创建一个按钮，并将它绑定到 generate_text 函数
#     generate_btn = gr.Button("Generate")
#     generate_btn.click(generate_text, inputs=[prompt], outputs=[output])
#
#     # 创建一个重新生成的按钮
#     regenerate_btn = gr.Button("Regenerate")
#     # 当点击再生按钮时，先调用 generate_text，然后调用 regenerate_text
#     regenerate_btn.click(fn=generate_text, inputs=[prompt], outputs=[output]).then(
#         fn=regenerate_text,
#         inputs=[],
#         outputs=[output]
#     )
#
# # 启动 Gradio 应用
# demo.launch()


# import gradio as gr
#
#
# # 定义一个包含 for 循环的方法
# def iterate_and_update(num_iterations, text1, text2):
#     for i in range(num_iterations):
#         # 模拟一些处理逻辑
#         a, b = epochs()
#         text1 +=a
#         text2 += b
#         print("----------------")
#         # 返回更新后的值
#         yield [gr.update(value=text1), gr.update(value=text2)]
#
# def iterate_and_update_plus(num_iterations_input, text1, text2):
#     for i in range(10):
#         text1, text2 = epochs(text1, text2)
#         return [gr.update(value=text1), gr.update(value=text2)]
#
# def epochs():
#     return "23", "34"
# # 创建 Gradio 界面
# with gr.Blocks() as demo:
#     with gr.Row():
#         # 创建一个输入框，用于输入迭代次数
#         num_iterations_input = gr.Number(label="迭代次数", value=5, precision=0)
#
#     with gr.Row():
#         # 创建两个 Textbox 组件，用于显示返回的值
#         text1 = gr.Textbox(label="值 1")
#         text2 = gr.Textbox(label="值 2")
#
#     chatbot = gr.Chatbot(elem_id="chatbot", label="InternVL-Chat", height=550)
#     with gr.Row():
#         # 创建一个按钮
#         button = gr.Button("开始迭代")
#         button2 = gr.Button("开始")
#
#     # 将按钮点击事件绑定到 iterate_and_update 函数
#     button.click(
#         fn=iterate_and_update,
#         inputs=[num_iterations_input, text1, text2],
#         outputs=[text1, text2]
#     )
#
#     button2.click(
#         fn=iterate_and_update,
#         inputs=[num_iterations_input, text1, text2],
#         outputs=[text1, text2]
#     )
#
# # 启动 Gradio 应用
# demo.launch()


#x学习Chatbot

# import gradio as gr  # 导入Gradio库
# import random  # 导入random库，用于生成随机回复
# import time  # 导入time库，用于控制延迟
#
# # 使用Gradio的Blocks构建一个应用程序界面
# with gr.Blocks() as demo:
#     chatbot = gr.Chatbot()  # 创建一个聊天机器人组件
#     msg = gr.Textbox()  # 创建一个文本框组件，用于用户输入消息
#     clear = gr.Button("Clear")  # 创建一个按钮组件，用于清除聊天历史
#
#
#     # 定义一个函数，用于处理用户消息并更新聊天历史
#     def user(user_message, history):
#         return "", history + [[user_message, None]]
#
#
#     # 定义一个函数，用于生成机器人的回复并逐字符更新聊天历史
#     def bot(history):
#         bot_message = random.choice(["How are you?", "I love you", "I'm very hungry"])
#         history[-1][1] = ""
#         for character in bot_message:
#             history[-1][1] += character
#             time.sleep(0.05)  # 每个字符之间添加0.05秒的延迟
#             yield history
#
#
#     # 当用户提交消息时，先调用user函数，然后调用bot函数
#     msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
#         bot, chatbot, chatbot
#     )
#     # 当点击清除按钮时，清除聊天历史
#     clear.click(lambda: None, None, chatbot, queue=False)
#
# # 启用队列功能
# demo.queue()
# # 启动应用程序
# demo.launch()

import gradio as gr

#模拟用户数据库
# import gradio as gr
#
# def methodchose(method):
#     if method == "保存生成图片":
#         return gr.update(visible=True)
#     else:
#         return gr.update(visible=False)
#
# with gr.Blocks() as demo:
#     with gr.Row():
#         save_imagePath = gr.Dropdown(choices=["不保存生成图片", "保存生成图片"], interactive=True, value="不保存生成图片", label="挑选是否保存图片")
#     with gr.Row() as base:
#         saveDir = gr.Textbox(placeholder="", label="保存图像的文件夹地址")
#     save_imagePath.change(fn=methodchose, inputs=[save_imagePath], outputs=[base])
#
# demo.launch()
#
# import gradio as gr
# import time
#
# def scrollable_textbox(text, val):
#     for i in range(100):
#         time.sleep(5)
#         print("i: ",i)
#         val = val + "\n" + text + "\n"
#         yield val
#
#
# # 创建一个可滚动的TextArea组件
# with gr.Blocks() as demo:
#     text_area = gr.TextArea(lines=20, label="滚动文本框")
#     text_box = gr.Text(lines=20, label="滚动文本框")
#     bn = gr.Button("提交")
#     bn.click(scrollable_textbox, inputs=[text_box, text_area], outputs=[text_area])
# demo.queue().launch()
# #


#
# import gradio as gr
# import time
# import asyncio
#
#
# async def scrollable_textbox(text):
#     # 初始化输出文本
#     output_text = ""
#     # 使用一个单独的循环来更新输出文本框内容
#     for i in range(1000):
#         await asyncio.sleep(400)  # 减少睡眠时间，以便更快地演示
#         output_text += f"{text}\n{i}\n"
#         yield output_text
#
# # 创建一个可滚动的TextArea组件
# with gr.Blocks(analytics_enabled=False) as demo:
#     # 输入文本框
#     inputText = gr.Text(label="输入文本")
#     # 进度文本框，初始时不可见
#     progress_box = gr.TextArea(lines=1, label="进度", visible=False)
#     # 输出文本框
#     output_box = gr.TextArea(lines=10, label="输出")
#
#     # 提交按钮
#     bn = gr.Button("提交")
#
#     # 先显示进度条
#     bn.click(scrollable_textbox, inputs=[inputText], outputs=[output_box])
#
# # 启动应用并启用队列功能
# demo.queue().launch(show_error=True)

# import gradio as gr
# import time
#
# async def scrollable_textbox(val, progress = gr.Progress()):
#     text = ""
#     for i in range(200):
#         time.sleep(500)
#         print("i: ",i)
#         val = val + "\n" + text + "\n"
#         progress(i/200, desc=f"Processing... {i+1}/100")
#     return val
#
#
# # 创建一个可滚动的TextArea组件
# with gr.Blocks() as demo:
#     text_area = gr.TextArea(lines=20, label="滚动文本框")
#     text_box = gr.Text(lines=2, label="输入文本框")
#     bn = gr.Button("提交")
#     bn.click(scrollable_textbox, inputs=[text_box], outputs=[text_area])
# demo.queue().launch()
#

# import gradio as gr
# import time
# from concurrent.futures import ThreadPoolExecutor, as_completed
#
#
# def scrollable_textbox(text, val, progress=gr.Progress()):
#     for i in range(100):
#         time.sleep(1)  # 减少 sleep 时间，以便更快地看到效果
#         print(f"i: {i}")
#         val = val + "\n" + text + f" {i + 1}\n"
#         progress(i / 100, desc=f"Processing... {i + 1}/100")
#         yield val
#
#
# # 创建一个可滚动的TextArea组件
# with gr.Blocks() as demo:
#     text_area = gr.TextArea(lines=20, label="滚动文本框")
#     text_box = gr.Textbox(lines=1, label="输入文本框")
#     bn = gr.Button("提交")
#
#
#     # 使用 queue 来处理后台任务
#     def start_thread(text, val, progress=gr.Progress()):
#         with ThreadPoolExecutor(max_workers=1) as executor:
#             future = executor.submit(list, scrollable_textbox(text, val, progress))
#             return future.result()[-1]  # 返回最后一次迭代的结果
#         print("end2")
#
#     # 设置按钮点击事件
#     bn.click(
#         fn=start_thread,
#         inputs=[text_box, text_area],
#         outputs=[text_area],
#         queue=True  # 启用队列处理
#     )
#     print("end")
#
# # 启动应用
# demo.queue().launch()



import gradio as gr
import time
import asyncio
from concurrent.futures import ThreadPoolExecutor

# 异步版本的 scrollable_textbox 函数
# async def scrollable_textbox(text, progress=gr.Progress()):
#     val = ''
#     for i in range(100):
#         await asyncio.sleep(70)  # 使用 asyncio.sleep 代替 time.sleep
#         print(f"i: {i}")
#         val = val + "\n" + text + f" {i + 1}\n"
#         progress(i / 100, desc=f"Processing... {i + 1}/100")
#         yield val
#
# # 创建一个可滚动的 TextArea 组件
# with gr.Blocks() as demo:
#     text_area = gr.TextArea(lines=6, label="滚动文本框")
#     text_box = gr.Textbox(lines=1, label="输入文本框")
#     bn = gr.Button("提交")
#
#
#
#     # 设置按钮点击事件
#     bn.click(
#         fn=scrollable_textbox,
#         inputs=[text_box],
#         outputs=[text_area],
#         queue=True  # 启用队列处理
#     )
#     print("end")
#
# # 启动应用
# demo.queue().launch()


# import time
# import gradio as gr
#
# def long_running_task(progress=gr.Progress()):
#     # 假设任务分为5个步骤
#     for i in range(100):
#         time.sleep(500)  # 模拟每个步骤需要的时间
#         # 更新进度条
#         progress(i+1, desc=f"Step {i+1} of 9")  # 这里我们假设总共有9个步骤
#     return "Task completed!"
#
# with gr.Blocks() as demo:
#     # 创建一个按钮来触发任务
#     start_button = gr.Button("Start Long Task")
#     # 创建一个文本输出组件来显示结果
#     output_text = gr.Textbox(label="Output")
#
#     # 当按钮被点击时，调用long_running_task函数
#     start_button.click(fn=long_running_task, outputs=output_text)
#
# # 启动 Gradio 界面
# demo.launch()

import gradio as gr
import asyncio
import concurrent.futures

# 定义普通的 addinput 函数
def addinput(text):
    return text + "123"

def add(x, y,x1,y1,x2,y2):
    for i in range(5):
        return x*y
# 定义异步的 scrollable_textbox 函数
async def scrollable_textbox(text):
    loop = asyncio.get_event_loop()
    with concurrent.futures.ThreadPoolExecutor() as pool:
        for i in range(10000):
            for j in range(10000):
                # 在单独的线程中执行耗时的操作
                result = await loop.run_in_executor(pool, lambda :add(i, j,i,j,j,i))
                print(f"i: {i}, j: {j}")
                text = text + "\n" + str(result) + "\n"
                yield text  # 逐步返回更新的文本内容

# 创建一个可滚动的 TextArea 组件
with gr.Blocks(analytics_enabled=False) as demo:
    text_area = gr.TextArea(label="滚动文本框")
    text_box = gr.Textbox(lines=2, label="输入文本框")
    bn = gr.Button("提交")

    # 定义一个异步函数来处理按钮点击事件
    async def handle_click(text):
        async for text_update in scrollable_textbox(text):
            print("2: ", text_update)
            # 更新文本区域
            yield text_update

    # 设置按钮点击事件
    bn.click(handle_click, inputs=[text_box], outputs=[text_area], queue=True)

    # 添加第二个按钮及其处理函数
    output1 = gr.TextArea(label="输出")
    input1 = gr.Textbox(lines=2, label="输入")
    bn2 = gr.Button("运行")
    bn2.click(addinput, inputs=[input1], outputs=[output1])

# 启动应用
demo.queue().launch(debug=True, show_error=True)
